package com.example.certificate.controller;


import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.certificate.annoatiton.CurrentUser;
import com.example.certificate.annoatiton.LoginToken;
import com.example.certificate.annoatiton.PassToken;
import com.example.certificate.dto.BasePageDTO;
import com.example.certificate.dto.OrderCarDTO;
import com.example.certificate.dto.UpProductDTO;
import com.example.certificate.entity.*;
import com.example.certificate.mapper.OrderFromMapper;
import com.example.certificate.mapper.ProductInfoMapper;
import com.example.certificate.service.OrderCartService;
import com.example.certificate.utils.ResultEntity;
import io.swagger.annotations.ApiOperation;
import jdk.nashorn.internal.ir.annotations.Ignore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import springfox.documentation.annotations.ApiIgnore;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author hao
 * @since 2022-03-10 12:25:41
 */
@RestController
@RequestMapping("/orderCart")
public class OrderCartController {

    @Autowired
    private OrderCartService cartService;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Resource
    private ProductInfoMapper productInfoMapper;

    @Resource
    private OrderFromMapper orderFromMapper;


    @LoginToken
    @PostMapping(value = "/addOrderCar")
    @ApiOperation("添加购物车功能")
    public ResultEntity addOrder(@RequestBody OrderCarDTO dto, @ApiIgnore @CurrentUser User user){
        cartService.addOrderCar(dto,user);
        return new ResultEntity();
    }

    @LoginToken
    @PostMapping(value = "/updateCar")
    @ApiOperation("修改购物车数量")
    public ResultEntity updateCar(@RequestBody OrderCarDTO dto,@ApiIgnore @CurrentUser User user){
        cartService.updateCar(dto,user);
        return new ResultEntity();
    }

    @LoginToken
    @PostMapping("/selCar")
    @ApiOperation("查询用户购物车")
    public ResultEntity selCar(@RequestBody BasePageDTO dto, @ApiIgnore @CurrentUser User user){
        Page<OrderCart> page=new Page<OrderCart>();
        page.setCurrent(dto.getCurrent()==null?1:dto.getCurrent());
        page.setSize(dto.getPageSize()==null?10:dto.getPageSize());
        return new ResultEntity(cartService.selOrderCar(page,user));
    }


    @PassToken
    @PostMapping("/selOrderCarDetail")
    @ApiOperation("结算详情")
    public ResultEntity selOrderCarDetail(@RequestBody OrderCarDTO dto){
        return cartService.selOrderCarDetail(dto.getProductId());
    }


    @LoginToken
    @PostMapping("/delProduct")
    @ApiOperation("用户删除购物车信息")
    public ResultEntity delProduct(@RequestBody OrderCarDTO dto, @ApiIgnore @CurrentUser User user){
        cartService.delProduct(dto,user);
        return new ResultEntity();
    }


    @LoginToken
    @PostMapping("/upCustomer")
    @ApiOperation("修改用户购物车信息数量")
    public ResultEntity upCustomer(@RequestBody UpProductDTO dto, @ApiIgnore @CurrentUser User user){
        cartService.upCustomer(dto,user);
        return new ResultEntity();
    }


    @PostMapping("/add")
    @ApiOperation(value = "收藏")
    @LoginToken
    public String addFavorite(@RequestBody OrderCarDTO dto, @CurrentUser @Ignore User user) {
        String key = "favorite:" + user.getId();
        long result = redisTemplate.opsForSet().add(key, dto.getProductId());
        redisTemplate.opsForZSet().add("favorite", dto.getProductId(), 1);
        return result > 0 ? "收藏成功" : "不能重复收藏";
    }

    @PostMapping("/delete")
    @LoginToken
    public String deleteFavorite(@RequestBody OrderCarDTO dto, @CurrentUser @Ignore User user) {
        String key = "favorite:" + user.getId();
        long result = redisTemplate.opsForSet().remove(key, dto.getProductId());

        Double score = redisTemplate.opsForZSet().score("favorite", dto.getProductId());

        if(score > 0)
            redisTemplate.opsForZSet().add("favorite", dto.getProductId(), score--);

        return result > 0 ? "取消收藏" : "未进行收藏";
    }

    @PostMapping("/count")
    public ResultEntity countFavorite(@RequestBody BasePageDTO dto) {

        List<ProductInfo> productInfos = new ArrayList<>();

        if(ObjectUtils.nullSafeEquals(dto.getTypeId(), "1")){
            Set<ZSetOperations.TypedTuple<String>> favorite = redisTemplate.opsForZSet().reverseRangeWithScores("detail", 0L, 9);
            for (ZSetOperations.TypedTuple<String> tuple : favorite) {
                // 4.1.获取userId
                ProductInfo productInfo = productInfoMapper.selectById(tuple.getValue());
                productInfos.add(productInfo);
            }
        }

        if(ObjectUtils.nullSafeEquals(dto.getTypeId(), "2")){
            Set<ZSetOperations.TypedTuple<String>> favorite = redisTemplate.opsForZSet().reverseRangeWithScores("favorite", 0L, 9);
            for (ZSetOperations.TypedTuple<String> tuple : favorite) {
                // 4.1.获取userId
                ProductInfo productInfo = productInfoMapper.selectById(tuple.getValue());
                productInfos.add(productInfo);
            }
        }

        if(ObjectUtils.nullSafeEquals(dto.getTypeId(), "3")){

            List<ProductInfo> productInfoList = new ArrayList<>();

            List<OrderFrom> orderFroms = orderFromMapper.selectList(new QueryWrapper<OrderFrom>().eq("status", 3));
            for (OrderFrom v:
                 orderFroms) {
                List<ProductInfo> productInfo = JSONArray.parseArray(v.getDetailDesc(), ProductInfo.class);
                productInfoList.addAll(productInfo);
            }

            Map<String, Long> collect4 = productInfoList.stream().collect(Collectors.groupingBy(ProductInfo::getId, Collectors.counting()));

            List<String> topTen =collect4.keySet().stream()
                    .sorted(Comparator.comparing(collect4::get))
                    .limit(10)
                    .collect(Collectors.toList());

            for (String v:
                    topTen) {

                ProductInfo productInfo = productInfoMapper.selectById(v);
                productInfos.add(productInfo);
            }

        }

        return new ResultEntity(productInfos);
    }

    //对值进行排序，此处为降序
    public static <K, V extends Comparable<? super V>> Map<K, V> sortByValueDescending(Map<K, V> map)
    {
        List<Map.Entry<K, V>> list = new LinkedList<Map.Entry<K, V>>(map.entrySet());
        Collections.sort(list, new Comparator<Map.Entry<K, V>>()
        {
            @Override
            public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2)
            {
                int compare = (o1.getValue()).compareTo(o2.getValue());
                return -compare;
            }
        });

        Map<K, V> result = new LinkedHashMap<K, V>();
        for (Map.Entry<K, V> entry : list) {
            result.put(entry.getKey(), entry.getValue());
        }
        return result;
    }

    @GetMapping("/list")
    @LoginToken
    public Set<String> listFavorite(@CurrentUser @Ignore User user) {
        String key = "favorite:" + user.getId();
        return redisTemplate.opsForSet().members(key);
    }
}

